DM-55381: Add @lsst-sqre/sse-client shared SSE transport package - #528
Open
jonathansick wants to merge 4 commits into
Open
DM-55381: Add @lsst-sqre/sse-client shared SSE transport package#528jonathansick wants to merge 4 commits into
jonathansick wants to merge 4 commits into
Conversation
Create packages/sse-client wrapping eventsource-client as the monorepo's shared SSE transport, exporting subscribeToEventSource() (raw message/connect/disconnect/reconnect callbacks, headers, credentials defaulting to 'include', external AbortSignal, fetch override, cleanup closes the client) and a thin useEventSource() React hook, so Times Square today and Semaphore later share one SSE primitive. Key decisions: - No payload parsing/validation in this layer; messages are delivered raw (EventSourceMessage) and consumers own their schemas. - External AbortSignal is wired to client.close(); an already-aborted signal skips connecting entirely and returns a no-op cleanup. - useEventSource reads options through a ref: only url changes reconnect; callback identity changes never do. url may be null to disable the subscription. - No-build-step package (main/types point at src/index.ts), react ^18||^19 peer dep, eventsource-client sole runtime dep; added to transpilePackages in apps/squareone/next.config.js. Next-iteration notes: - Tests use a mocked FetchLike returning a ReadableStream SSE body (honoring init.signal with an AbortError); the helper is duplicated in both test files and could be shared if task #526 needs it. - EventSourceMessage and FetchLike are re-exported from src/index.ts for consumers (times-square-client in #526). Closes #525
🦋 Changeset detectedLatest commit: 12f3adb The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Closed
5 tasks
Rebuild subscribeToHtmlEvents() on the shared subscribeToEventSource() transport, dropping the unmaintained @microsoft/fetch-event-source dependency while preserving the public SSE API exactly. Key decisions: - Zod validation, auto-abort on complete+html_hash, onComplete, and the structured Logger stay in this layer; the transport stays raw. - Reconnect policy is the library default (automatic backoff honoring server retry:, including after 4xx); connection loss is surfaced via onError from onDisconnect, and scheduled reconnects are logged at debug level through the Logger. - sse.test.ts mocks @lsst-sqre/sse-client at the module boundary and drives the captured callbacks directly, keeping the tests focused on this layer's semantics rather than transport behavior. - Changeset is minor: no API change, but the reconnect-after-4xx behavior and transpile graph (sse-client source) change for consumers. Next-iteration notes: - Task #527 (app provider refactor) can rely on subscribeToHtmlEvents signatures being unchanged; @lsst-sqre/sse-client is already in apps/squareone transpilePackages from task #525. - @microsoft/fetch-event-source still remains in apps/squareone package.json; #527 removes the last repo reference. Closes #526
5 tasks
Rewrite TimesSquareHtmlEventsProviderClient on the packaged
subscribeToHtmlEvents() from @lsst-sqre/times-square-client, deleting the
duplicated inline fetchEventSource logic and the local HtmlEvent type. The
app's SSE path now gains Zod validation, credentials: 'include', and
automatic reconnection from the shared transport, and
@microsoft/fetch-event-source is removed from the entire repo.
Key decisions:
- The provider's isClient gate was dropped: the component is loaded via
next/dynamic with ssr: false and useEffect never runs on the server, so
the extra state only forced a redundant effect cycle.
- The URL query string from TimesSquareUrlParametersContext is converted to
a params record with URLSearchParams so subscribeToHtmlEvents owns URL
construction (no more manual `?${qs}` concatenation).
- The dev mock github/[...tsSlug] route drifted from the client's PageSchema
(string description, missing date_added/uploader_username), which Zod-failed
useTimesSquarePage and blocked the end-to-end SSE check; it was minimally
updated to conform.
Next-iteration notes:
- The dev mock /times-square/api/v1/github contents route still fails
GitHubContentsRootSchema validation (console ZodError on Times Square pages
in dev; sidebar nav 404s). Pre-existing drift, out of scope here.
Closes #527
5 tasks
Update the vendored Times Square OpenAPI spec to v0.24.0 and fix the dev mock API routes that had drifted from it: - The GitHub contents-tree mocks (github and github-pr) omitted the required contents array on leaf page nodes, which failed GitHubContentsRootSchema/GitHubPrContentsSchema validation and broke the sidebar nav in dev. - The pages/[page] and github-pr page-metadata mocks still returned a plain-string description and lacked date_added, uploader_username, html_events_url, and github required by PageSchema. Mock payloads are now typed with the Page/GitHubContentsRoot/ GitHubPrContents types from @lsst-sqre/times-square-client for compile-time conformance, and a new schema-conformance test parses every JSON mock route with the package's Zod schemas so future drift fails in CI instead of as a runtime ZodError in dev.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@lsst-sqre/sse-client, a new minimal workspace package wrappingeventsource-clientas the monorepo's shared SSE transport, replacing the unmaintained@microsoft/fetch-event-source. It exportssubscribeToEventSource(url, options)— raw message/connect/disconnect/reconnect callbacks, customheaders,credentialsdefaulting to'include'(Gafaelfawr same-origin cookie auth), externalAbortSignal,fetchoverride, with a cleanup function that closes the client — and a thinuseEventSource()React hook. No payload parsing/validation in this layer; consumers own their schemas.@lsst-sqre/times-square-client's SSE layer (subscribeToHtmlEvents()) onsubscribeToEventSource(), preserving the public API exactly. Zod validation ofHtmlEvent, auto-abort on execution completion,onComplete, and the optional structuredLoggerstay in this layer; reconnect policy follows the transport default (automatic backoff honoring serverretry:, including after 4xx), with connection loss surfaced viaonErrorand scheduled reconnects logged through theLogger.TimesSquareHtmlEventsProviderClientto the packagedsubscribeToHtmlEvents(), deleting its duplicated inlinefetchEventSourcelogic and localHtmlEventtype; the app's SSE path gains Zod validation,credentials: 'include', and automatic reconnection.@microsoft/fetch-event-sourceis now removed from everypackage.jsonin the repo. Also conforms the dev mockgithub/[...tsSlug]route to the client'sPageSchemaso the dev-mode Times Square flow works end-to-end.main/typespoint atsrc/index.ts; consumers transpile) and register the package intranspilePackagesinapps/squareone/next.config.js. Includes changesets for@lsst-sqre/sse-client(new),@lsst-sqre/times-square-client, andsquareone.Validation steps
pnpm installand confirm it succeeds witheventsource-clientpresent only inpackages/sse-client, and thatgrep -r "fetch-event-source"across the repo'spackage.jsonfiles and source returns no matches.pnpm test --filter @lsst-sqre/sse-client --filter @lsst-sqre/times-square-clientfrom the repo root and confirm the SSE tests pass (transport: message delivery, connect/disconnect callbacks, cleanup, external abort; Times Square layer: valid event →onEvent, malformed JSON ignored, Zod-invalid payload rejected with logger warning, auto-abort +onCompleteon completion, cleanup aborts).@lsst-sqre/sse-clientis listed intranspilePackagesinapps/squareone/next.config.js.subscribeToHtmlEvents()call sites inapps/squareonecompile unchanged, and thatTimesSquareHtmlEventsProviderClient.tsxcontains no inline SSE parsing and no localHtmlEventtype.pnpm dev --filter squareone, open/times-square/github/lsst-sqre/times-square-demo/matplotlib/gaussian2d?a=1and confirm the page receives the mock SSE event (execution stats render, e.g. "in 14.2 seconds"), context values update, and thehtmleventsconnection closes after thecompleteevent (a single request in the Network tab, no reconnect loop).References